package com.ruoyi.exam.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.exam.domain.ExamUserPracticeRecord;
import com.ruoyi.exam.vo.*;
import com.ruoyi.exam.mapper.ExamBankQuestionMapper;
import com.ruoyi.exam.mapper.ExamQuestionBankMapper;
import com.ruoyi.exam.mapper.ExamUserBankProgressMapper;
import com.ruoyi.exam.mapper.ExamUserPracticeRecordMapper;
import com.ruoyi.exam.service.IExamUserPracticeRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户刷题记录Service业务层处理
 *
 * @author Tellsea
 * @date 2025-06-23
 */
@Service
public class ExamUserPracticeRecordServiceImpl extends ServiceImpl<ExamUserPracticeRecordMapper, ExamUserPracticeRecord> implements IExamUserPracticeRecordService {

    @Autowired
    private ExamBankQuestionMapper examBankQuestionMapper;

    @Autowired
    private ExamQuestionBankMapper examQuestionBankMapper;

    @Autowired
    private ExamUserBankProgressMapper examUserBankProgressMapper;

    @Override
    public TableDataInfo<ExamUserPracticeRecordVo> queryList(ExamUserPracticeRecordVo entity) {
        return PageUtils.buildDataInfo(this.baseMapper.queryList(PageUtils.buildPage(), entity));
    }

    @Override
    public List<ExamUserPracticeRecordVo> queryAll(ExamUserPracticeRecordVo entity) {
        return this.baseMapper.queryList(entity);
    }

    @Override
    public ExamUserPracticeRecordVo queryById(Long recordId) {
        return this.baseMapper.queryById(recordId);
    }

    @Override
    public List<ExamUserPracticeRecordVo> getByUserIdAndBankId(Long userId, Long bankId) {
        return this.baseMapper.getByUserIdAndBankId(userId, bankId);
    }

    @Override
    public BankQuestionPracticeInfoVo getBankQuestionPracticeInfo(Long userId, Long bankId) {
        BankQuestionPracticeInfoVo result = new BankQuestionPracticeInfoVo();

        // 1. 获取题库进度信息
        BankProgressInfoVo progressInfo = examQuestionBankMapper.getBankProgressInfo(bankId, userId);
        result.setProgressInfo(progressInfo);

        // 2. 获取题库的所有题目（按顺序）
        List<ExamQuestionWithSortVo> bankQuestions = examBankQuestionMapper.getQuestionsByBankId(bankId);

        // 3. 获取用户在该题库的答题记录
        List<ExamUserPracticeRecordVo> practiceRecords = this.baseMapper.getByUserIdAndBankId(userId, bankId);

        // 4. 将答题记录转换为Map，方便查找
        Map<Long, ExamUserPracticeRecordVo> recordMap = new HashMap<>();
        if (practiceRecords != null) {
            for (ExamUserPracticeRecordVo record : practiceRecords) {
                recordMap.put(record.getQuestionId(), record);
            }
        }

        // 5. 组装题目答题状态列表，并查找未开始答的第一题
        List<QuestionPracticeStatusVo> questionList = new ArrayList<>();
        Long firstUnansweredQuestionId = null;
        Integer firstUnansweredQuestionIndex = null;
        
        // 检查用户是否完全没有答题记录
        boolean hasNoRecords = practiceRecords == null || practiceRecords.isEmpty();
        
        if (bankQuestions != null) {
            for (int i = 0; i < bankQuestions.size(); i++) {
                ExamQuestionWithSortVo question = bankQuestions.get(i);
                QuestionPracticeStatusVo statusVo = new QuestionPracticeStatusVo();
                statusVo.setQuestionId(question.getQuestionId());
                statusVo.setSortOrder(question.getSortOrder());

                // 检查是否有答题记录
                ExamUserPracticeRecordVo record = recordMap.get(question.getQuestionId());
                if (record != null) {
                    statusVo.setHasAnswered(true);
                    // "1"表示正确，"0"表示错误
                    statusVo.setIsCorrect("1".equals(record.getIsCorrect()));
                } else {
                    statusVo.setHasAnswered(false);
                    statusVo.setIsCorrect(null);
                    
                    // 如果是第一个未答题的题目，记录其ID和索引
                    if (firstUnansweredQuestionId == null) {
                        firstUnansweredQuestionId = question.getQuestionId();
                        firstUnansweredQuestionIndex = i;
                    }
                }

                questionList.add(statusVo);
            }
            
            // 如果用户完全没有答题记录，或者题库已完成，返回题库的第一题ID和索引
            if ((hasNoRecords || "1".equals(progressInfo.getIsCompleted())) && !bankQuestions.isEmpty()) {
                firstUnansweredQuestionId = bankQuestions.get(0).getQuestionId();
                firstUnansweredQuestionIndex = 0;
            }
        }

        result.setQuestionList(questionList);
        result.setFirstUnansweredQuestionId(firstUnansweredQuestionId);
        result.setFirstUnansweredQuestionIndex(firstUnansweredQuestionIndex);

        return result;
    }

    @Override
    public BankWrongQuestionInfoVo getBankWrongQuestionInfo(Long userId, Long bankId) {
        BankWrongQuestionInfoVo result = new BankWrongQuestionInfoVo();

        // 1. 获取用户在指定题库中的错题列表
        List<MyWrongQuestionVo> wrongQuestions = this.baseMapper.queryWrongQuestionsByUserIdAndBankId(userId, bankId);
        result.setWrongQuestions(wrongQuestions);

        // 2. 设置错题总数
        result.setTotalCount(wrongQuestions != null ? wrongQuestions.size() : 0);

        // 3. 获取用户在该题库的答题记录
        List<ExamUserPracticeRecordVo> practiceRecords = this.baseMapper.getByUserIdAndBankId(userId, bankId);

        // 4. 将答题记录转换为Map，方便查找
        Map<Long, ExamUserPracticeRecordVo> recordMap = new HashMap<>();
        if (practiceRecords != null) {
            for (ExamUserPracticeRecordVo record : practiceRecords) {
                recordMap.put(record.getQuestionId(), record);
            }
        }

        // 5. 组装题目答题状态列表，并查找未开始答的第一题
        List<QuestionPracticeStatusVo> questionList = new ArrayList<>();
        if (wrongQuestions != null && !wrongQuestions.isEmpty()) {
            for (int i = 0; i < wrongQuestions.size(); i++) {
                MyWrongQuestionVo wrongQuestion = wrongQuestions.get(i);
                QuestionPracticeStatusVo statusVo = new QuestionPracticeStatusVo();
                statusVo.setQuestionId(wrongQuestion.getQuestionId());
                statusVo.setSortOrder((long) i); // 使用错题列表中的索引作为排序
                
                // 检查是否有答题记录
                ExamUserPracticeRecordVo record = recordMap.get(wrongQuestion.getQuestionId());
                if (record != null) {
                    statusVo.setHasAnswered(true);
                    // "1"表示正确，"0"表示错误
                    statusVo.setIsCorrect("1".equals(record.getIsCorrect()));
                } else {
                    statusVo.setHasAnswered(false);
                    statusVo.setIsCorrect(null);
                }
                questionList.add(statusVo);
            }
            result.setFirstUnansweredQuestionId(wrongQuestions.get(0).getQuestionId());
            result.setFirstUnansweredQuestionIndex(0);
        }
        result.setQuestionList(questionList);
        return result;
    }

    @Override
    public List<BankProgressInfoVo> getAllBankProgressInfo(Long userId) {
        List<BankProgressInfoVo> resultList = new ArrayList<>();

        // 查询用户关联的题库列表
        List<ExamQuestionBankVo> myBanks = examQuestionBankMapper.myQuestionBankList(userId);
        if (myBanks == null || myBanks.isEmpty()) {
            return resultList;
        }

        // 逐个题库汇总进度信息
        for (ExamQuestionBankVo bank : myBanks) {
            if (bank == null || bank.getBankId() == null) {
                continue;
            }
            BankProgressInfoVo progressInfo = examQuestionBankMapper.getBankProgressInfo(bank.getBankId(), userId);
            if (progressInfo != null) {
                resultList.add(progressInfo);
            }
        }

        return resultList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean resetBankProgress(Long userId, Long bankId) {
        // 删除题库进度
        int deletedProgress = examUserBankProgressMapper.delete(
                new QueryWrapper<com.ruoyi.exam.domain.ExamUserBankProgress>()
                        .eq("user_id", userId)
                        .eq("bank_id", bankId)
        );

        // 删除刷题记录
        int deletedRecords = this.baseMapper.delete(
                new QueryWrapper<com.ruoyi.exam.domain.ExamUserPracticeRecord>()
                        .eq("user_id", userId)
                        .eq("bank_id", bankId)
        );

        // 只要操作未抛异常即视为成功
        return deletedProgress >= 0 && deletedRecords >= 0;
    }
}
